/*
 * @Author: fangquan
 * @Date: 2020-6-19 10:00:00
 * @Last Modified by: fangquan
 * @Last Modified time: 2020-6-19 10:00:00 
 * @Usage 二次封装、增加请求拦截
 */

import axios from "axios";
import qs from "qs";
import device from "./device";

import { formatParams } from "./common";

import { Toast } from "vant";

const DEFAULT_HEADER = {
  "Content-Type": "application/x-www-form-urlencoded",
};

const ERROR_MESSAGE = "服务器异常，请刷新重试";
const APP_TYPE = process.env.VUE_APP_TYPE;
const NEED_REDIRECT =
  formatParams().unauth != 1 && (device.wechat || device.weibo); // 是否需要重定向授权
const NEED_RELOGIN = [402, 404, 405]; // 需要重新登录的状态码

let authing = false;

// ---- 默认设置 ----
axios.defaults.baseURL = APP_TYPE == "development" ? "/api" : "";
axios.defaults.timeout = 15000;
axios.defaults.headers = DEFAULT_HEADER;

// ---- 请求拦截 ----
axios.interceptors.request.use(
  (config) => {
    return config;
  },
  (error) => {
    return Promise.reject(error);
  }
);

// ---- 响应拦截 ----
axios.interceptors.response.use(
  (response) => {
    return response;
  },
  (error) => {
    return Promise.reject(error);
  }
);

// ---- 封装增、删、改、查方法 ----
let request = new Object();

["post", "del", "put", "get"].forEach((method) => {
  request[method] = (url, data, extra = {}) =>
    new Promise((resolve, reject) => {
      let {
        headers = {},
        showLoading = true,
        showToast = true,
        mask = false,
      } = extra;

      if (
        !(data && data.access_token) &&
        headers["Content-Type"] != "multipart/form-data"
      ) {
        data = {
          ...data,
          access_token: localStorage.getItem("access_token"),
        };
      }

      // 上传和json传参免序列化
      let ignoreQs =
        headers &&
        ["multipart/form-data", "application/json"].includes(
          headers["Content-Type"]
        );

      // 请求参数
      let params =
        method == "get"
          ? {
              method,
              url: url,
              params: data,
              headers: headers,
              withCredentials: true,
              crossDomain: true,
            }
          : {
              method,
              url: url,
              //兼容上传文件
              data: ignoreQs
                ? data
                : typeof data == "string"
                ? data
                : qs.stringify(data),
              headers: headers,
              withCredentials: true,
              crossDomain: true,
            };

      let toast = null;

      // 显示加载中Toast
      if (showLoading)
        toast = Toast.loading({
          message: "正在加载",
          duration: 0,
          mask,
          forbidClick: true,
        });

      // 开始请求数据
      axios(params)
        .then((res) => {
          let { code, message } = res.data;

          // 未授权/重新登录处理
          if (NEED_RELOGIN.includes(code) && NEED_REDIRECT) {
            localStorage.removeItem("access_token"); // 清除当前过期token

            let url = location.href.replace("&code=", "&oldCode=");

            // 授权跳回来之后，如果还是未授权，就return，防止重复跳
            // let url = location.href.replace("&code=", "&oldCode=") + "&reload=1";
            // if (formatParams().reload == 1) return false;

            // 防止出现多次授权弹窗
            if (!authing) {
              authing = true;

              if (device.weibo) {
                // 微博授权
                location.replace(
                  `https://api.weibo.com/oauth2/authorize?client_id=3133623028&response_type=code&redirect_uri=${encodeURIComponent(
                    url
                  )}`
                );
              } else {
                // 微信授权
                let scope =
                  formatParams().silence == 1
                    ? "snsapi_base"
                    : "snsapi_userinfo"; // 是否开启静默授权
                location.replace(
                  `https://open.weixin.qq.com/connect/oauth2/authorize?appid=${localStorage.getItem(
                    "appId"
                  )}&redirect_uri=${encodeURIComponent(
                    url
                  )}&response_type=code&scope=${scope}&state=1#wechat_redirect`
                );
              }
            }
          }

          resolve(res.data);

          if (code != 200 && !NEED_RELOGIN.includes(code) && showToast)
            return Toast(message || ERROR_MESSAGE); // 错误提示

          toast && toast.clear(); // 清除toast
        })
        .catch((err) => {
          showToast && Toast(ERROR_MESSAGE);

          reject(err);
        });
    });
});

export default request;
